package org.ihelpuoo.weboo.tag;

import java.io.IOException;
import java.util.Locale;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.ihelpuoo.core.Nut;
import org.ihelpuoo.lang.SegmentNotFoundException;
import org.ihelpuoo.lang.StringUtils;
import org.ihelpuoo.parser.segment.Segment;
import org.ihelpuoo.parser.segment.SegmentFactory;
import org.ihelpuoo.weboo.WebooUtils;
import org.ihelpuoo.weboo.exception.ModuleNotFoundException;
import org.ihelpuoo.weboo.module.Module;
import org.ihelpuoo.weboo.module.ModuleContext;
import org.ihelpuoo.weboo.module.ModuleManager;
import org.ihelpuoo.weboo.module.WebooConfig;
import org.ihelpuoo.weboo.security.Session;
import org.ihelpuoo.weboo.security.SessionImpl;

public abstract class WebooTag extends BodyTagSupport
{
	protected abstract void start() throws JspException;

	protected abstract void end() throws JspException;

	private String	_body;

	@Override
	public int doEndTag() throws JspException
	{
		if (null != bodyContent)
			this._body = bodyContent.getString();
		end();
		return super.doEndTag();
	}

	public String getBodyString()
	{
		return _body;
	}

	public String getBodyStringTrimed()
	{
		return StringUtils.trim(_body);
	}

	public boolean isEmptyBody()
	{
		return StringUtils.isEmpty(_body);
	}

	public boolean isBlankBody()
	{
		return StringUtils.isBlank(_body);
	}

	@Override
	public int doStartTag() throws JspException
	{
		getWebooConfig().initContextPath((HttpServletRequest)pageContext.getRequest());
		start();
		return super.doStartTag();
	}

	private static final String	CURRENT_MODULE	= "CURRENT_MODULE";

	protected ServletRequest getRequest()
	{
		return this.pageContext.getRequest();
	}

	protected ModuleManager getModuleManager()
	{
		return ModuleManager.me(pageContext.getServletContext());
	}

	protected Module getModule(String name) throws ModuleNotFoundException
	{
		if (null == name)
			return this.getCurrentModule();
		return getModuleManager().getModule(name);
	}

	protected Module getCurrentModule() throws ModuleNotFoundException
	{
		Module m = (Module)pageContext.getAttribute(CURRENT_MODULE);
		if (null == m)
		{
			String path = ((HttpServletRequest)pageContext.getRequest()).getServletPath();
			StringBuffer sb = new StringBuffer();
			WebooUtils.getModuleNameFromPath(path,sb);
			m = getModule(sb.toString());
			pageContext.setAttribute(CURRENT_MODULE,m);
		}
		return m;
	}

	protected WebooConfig getWebooConfig()
	{
		return WebooConfig.me(pageContext.getServletContext());
	}

	public String getString(String key)
	{
		Object v = getValue(key);
		return (v == null ? null : v.toString());
	}

	public int getInt(String k)
	{
		Object v = getValue(k);
		if (null == v)
			return -1;
		return Integer.parseInt(v.toString());
	}

	public boolean getBoolean(String k)
	{
		Object v = getValue(k);
		if (null == v)
			return false;
		return Boolean.parseBoolean(v.toString());
	}

	public String getRootPath()
	{
		return getWebooConfig().getRootPath();
	}

	public Session getSession()
	{
		return SessionImpl.wrap(pageContext);
	}

	public Locale getLocale()
	{
		return getSession().getLocale();
	}

	public Segment createPattern(String name) throws SegmentNotFoundException
	{
		try
		{
			return createPattern(name,null);
		}
		catch (ModuleNotFoundException e)
		{
			throw new RuntimeException(e);
		}
	}

	public Segment createSegment(String name) throws SegmentNotFoundException
	{
		return getWebooConfig().segments().create(name);
	}

	public Segment createPattern(String name, String moduleName) throws SegmentNotFoundException,
			ModuleNotFoundException
	{
		return this.getModule(moduleName).getModuleContext().patterns(getLocale()).create(
				getWebooConfig().formatPatternName(name));
	}

	public Nut nut()
	{
		return this.getWebooConfig().nut();
	}

	public ProcessContext getProcessContext(String name) throws ModuleNotFoundException
	{
		ModuleContext mc = getModule(name).getModuleContext();
		return new ProcessContext(mc,pageContext);
	}

	public String getContextPath()
	{
		return ((HttpServletRequest)pageContext.getRequest()).getContextPath();
	}

	public SegmentFactory segments()
	{
		return this.getWebooConfig().segments();
	}

	public void write(String s) throws JspException
	{
		try
		{
			pageContext.getOut().write(s);
		}
		catch (IOException e)
		{
			throw new JspException(e);
		}
	}
}
